home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
tcp_ip
/
gp
/
7plsrc.lzh
/
ENCODE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-22
|
12KB
|
386 lines
#include "7plus.h"
#include "globals.h"
/*
*** encode a file. split, if desired/needed. create correction file.
***
***
*/
int encode_file (char *name, long blocksize, char *searchbin)
{
int part, parts, blockzeilen, lfd_zeile;
int correct, corrzeilen, corrpart, corrzeile;
uint csequence;
ulong danach[16], *dn, h;
long binbytes, binb0, position, size;
char destname[13], hdrname[MAXFNAME], filename[13], corrname[13];
char orgname[66], inpath[MAXFPATH], zeile[81], zeile2[81];
char dummi[20], dummi2[20], *q, *r;
FILE *rein, *raus, *corr;
register i, j, k;
correct = i = 0;
*destname = *hdrname = *filename = *corrname = *inpath = *orgname = EOS;
*_file = EOS;
raus = NULL;
if (fls)
if (!test_exist ("7plus.fls"))
unlink ("7plus.fls");
if (searchbin)
{
/* Get serchpath for binary (original) file. */
fnsplit (searchbin, _drive, _dir, _file, _ext);
sprintf (inpath, "%s%s", _drive, _dir);
}
q = name;
/* create correction file, if ext of input file is .ERR */
if ((r = strrchr (q, '.')) != NULL)
if (!strnicmp (".err", r, 4))
{
/* OK, input file is an error file */
correct = 1;
if (crc_file (q, "7PLUS error", "00\n", 1) == 1)
return (7);
corr = fopen (q, OPEN_READ_TEXT);
/* Find starting line. */
while ((r = my_fgets (zeile, 80, corr)) != NULL)
if (!strncmp (zeile, "7PLUS ", 6))
break;
if (!r)
{
printf ("\007'%s': invalid error report. Break.\n", q);
fclose (corr);
return (7);
}
/* Get name, lines per part, and length of original file from error file.*/
*orgname = EOS;
binb0 = 0L;
sscanf (zeile+20, "%12s %s /%66[^/]/ %ld",
corrname, dummi, orgname, &binb0);
corrzeilen = get_hex (dummi);
if (!*orgname)
{
binb0 = 0L;
sscanf (zeile+20, "%s %s %ld", dummi, dummi, &binb0);
}
strlwr (corrname);
if (extended != '*' || !*orgname)
strcpy (orgname, corrname);
/* Build complete filename for original file */
if (!*_file)
strcat (inpath, orgname);
else
{
strcat (inpath, _file);
strcat (inpath, _ext);
}
q = inpath;
}
if ((rein = fopen (q, OPEN_READ_BINARY)) == NULL)
{
printf ("\007'%s' not found. Break.\n", q);
return (2);
}
/* determine size of original file. This could be done with filestat(),
but it's not available on all compilers. */
fseek (rein, 0L, SEEK_END); /* position read pointer to end of file. */
size = ftell (rein); /* get size. */
fseek (rein, 0L, SEEK_SET); /* reposition to beginning of file. */
if (correct && binb0 && size != binb0)
{
printf (notsame, "error report");
return (15);
}
part = parts = 1;
if (!correct)
{
/* Bufferize input, if we're encoding. */
setvbuf (rein, NULL, _IOFBF, buflen);
/* if blocksize is greater then try to split into blocksize-50000 parts */
if (blocksize > 50000L)
{
blocksize -= 50000L;
/* calculate how many assci-bytes per part are needed to get roughly
equal filelengths. */
blocksize = (((size + 61) / 62) + (blocksize - 1)) / blocksize;
blocksize *= 62;
}
/* if blocksize is defined as zero or if it's bigger than the file,
set it to filelength */
if (!blocksize || blocksize > size)
blocksize = size;
/* automatically split into 512 line parts, if file is bigger. */
if (blocksize > (512 * 62))
{
blocksize = 512 * 62;
printf ("Blocksize limited to 512 lines per file.\n");
}
/* how many lines do the parts contain? */
blockzeilen = (int) ((blocksize + 61) / 62);
/* how many parts result from that? */
parts = (int) ((size + blocksize-1) / blocksize);
if (parts > 255)
{
printf ("\007Not more than 255 parts allowed.\n");
printf ("Choose different blocksize. Break.\n");
return (8);
}
}
/* generate filenames */
fnsplit (q, NULL, NULL, _file, _ext);
sprintf (orgname, "%s%s", _file, _ext);
build_DOS_name (_file);
build_DOS_name (_ext);
/* make sure, the name isn't longer than 8 chars
and extension not longer 4 (including dot). */
_file[8] = _ext[3] = EOS;
strcpy (destname, _file);
sprintf (hdrname, "%s%s%s", _file, _ext[0]?".":"", _ext);
strupr (hdrname);
printf ("\n");
/* encode parts */
for (part=1; part<parts+1 ; part++)
{
if (!correct)
{
/* generate output filename. *.7PL, if unsplit. *.PXX if split.
XX represents a two digit hex number. */
if (parts == 1)
{
sprintf (filename, "%s%s", destname, ".7pl");
printf ("'%s': Writing.\r", filename);
}
else
{
sprintf (filename, "%s.p%02x", destname, part);
printf ("'%s': Writing part %03d of %03d.\r", filename, part, parts);
}
fflush (stdout);
/* check, if output file already exists. */
test_file (raus, filename, 0, 12);
}
else /* we're creating a correction file, set name accordingly. */
{
fnsplit (corrname, NULL, NULL, destname, NULL);
sprintf (filename, "%s.cor", destname);
}
raus = fopen (filename, OPEN_WRITE_TEXT);
setvbuf (raus, NULL, _IOFBF, buflen);
if (!correct)
{
if (part == parts && parts > 1)
{
if (size % blocksize)
blocksize = size % blocksize;
blocksize = ((blocksize + 61 ) / 62) *62;
}
/* output header */
sprintf (zeile, " go_7+. %03d of %03d %-12s %07ld %04X %03X (7PLUS v1.6) \
\xb0\xb1\xb2%c", part, parts, hdrname, size,
(uint)(((blocksize+61)/62) * 64), blockzeilen,
extended);
mcrc (zeile, 1);
add_crc2 (zeile);
fprintf (raus, "%s%s", zeile, delimit);
if (part == 1 && extended == '*')
{
sprintf (zeile, "///////////////////////////////////////////////////\
///////////\xb0\xb1\xb2*");
strcpy (zeile+1, orgname);
zeile[(int)strlen(orgname)+1] = '/';
mcrc (zeile, 1);
add_crc2 (zeile);
fprintf (raus, "%s%s", zeile, delimit);
}
}
else
{
/* output correction file header */
strcpy (dummi2, filename);
strupr (dummi2);
fprintf (raus, " go_text. %s%s", dummi2, delimit);
strupr (corrname);
fprintf (raus, "7PLUS correction: %s %ld%s", corrname, size, delimit);
strlwr (corrname);
fscanf (corr, "%s", dummi2);
corrpart = get_hex (dummi2);
fprintf (raus, " P%02x:%s", corrpart, delimit);
}
lfd_zeile = j = 0;
binbytes = 0L;
/* get bytes from original file until it ends or blocksize is reached. */
while (!feof(rein) && ((binbytes < blocksize) || parts == 1))
{
csequence = 0;
if (correct)
{
/* get number of part and number of line to put into correction file
from error file */
fscanf (corr, "%s", dummi2);
corrzeile = get_hex (dummi2);
if (corrzeile == 0xfff)
{
corrpart = 0;
fscanf (corr, "%s", dummi2);
corrpart = get_hex (dummi2);
if (!corrpart)
break;
fprintf (raus, " P%02x:%s", corrpart, delimit);
fscanf (corr, "%s", dummi2);
corrzeile = get_hex (dummi2);
}
lfd_zeile = corrzeile;
/* calculate position in original file to get data from. */
position = (long)(corrpart-1) * 62 * (long)corrzeilen +
62 * (long)corrzeile ;
/* position read pointer. */
fseek (rein, position, SEEK_SET);
fprintf (raus, " L%03X:%s", corrzeile, delimit);
}
/* get two groups of 31 bytes and stuff them into 2 * 8 longs. */
dn = danach;
for (i=0; i<2; i++, dn+=8)
{
/* Get 31 Bytes and put them into 8 longs. */
for(j=0; j<8; j++)
{
dn[j] = 0L;
for (k=(j==7)?2:3; k>-1; k--)
{
if ((h = fgetc (rein)) == EOF)
{
if (!i && !j && k == 3)
i = 255;
h = 0L;
}
dn[j] = (dn[j] << 8) | h;
}
}
/* Rearrange into 8 31bit values. */
dn[7] = dn[7] | ((dn[6] & 127L) << 24);
dn[6] = (dn[6] >> 7) | ((dn[5] & 63L ) << 25);
dn[5] = (dn[5] >> 6) | ((dn[4] & 31L ) << 26);
dn[4] = (dn[4] >> 5) | ((dn[3] & 15L ) << 27);
dn[3] = (dn[3] >> 4) | ((dn[2] & 7L ) << 28);
dn[2] = (dn[2] >> 3) | ((dn[1] & 3L ) << 29);
dn[1] = (dn[1] >> 2) | ((dn[0] & 1L ) << 30);
dn[0] = (dn[0] >> 1);
}
/* i is 256, then no bytes were read. End of file. */
if (i == 256)
break;
binbytes += 62;
/* write code line to output file. do radix216 conversion, crc
calculation and ascii conversion as we go along. */
for (i=j=0;i<16;i++)
{
zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
danach[i] /= 0xd8L;
zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
danach[i] /= 0xd8L;
zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
zeile2[j++] = code[(int)(danach[i] / 0xd8L)];
}
for (i=0;i<64;i++)
csequence = crctab[csequence>>8] ^ (((csequence&255)<<8) |
(byte) zeile2[i]);
/* package line number and crc into three radix216 bytes and add
to code line. */
danach[0] = ((long)(lfd_zeile & 0x1ff) << 14) | (csequence & 0x3fff);
zeile2[j++] = code[(int) (danach[0] % 0xd8L)];
danach[0] /= 0xd8L;
zeile2[j++] = code[(int) (danach[0] % 0xd8L)];
zeile2[j++] = code[(int) (danach[0] / 0xd8L)];
add_crc2 (zeile2);
fprintf (raus, "%s", zeile2);
/* conclude line with line separator. */
fprintf (raus, delimit);
lfd_zeile++; /* increase line counter. */
}
if (!correct) /* put end indicator into output file. */
{
strupr (filename);
fprintf (raus, " stop_7+. (%s)%s", filename, delimit);
}
else
{
/* if we were creating correction file, complete it. */
fprintf (raus, " P00:%s", delimit);
fclose (raus);
crc_file (filename, "7P", " P00:\n", 0);
raus = fopen (filename, OPEN_APPEND_TEXT);
fprintf (raus, " stop_text.%s", delimit);
}
if (endstr)
fprintf (raus, "%s%s", endstr, delimit);
if (ferror(raus)) /* did any errors occur while writing? */
{
printf ("\n\007Write error. Break.\n");
fclose (rein);
return (1);
}
/* OK. This part is done. */
fclose (raus);
} /* end of for() */
/* all parts done.
tell user about action. */
if (correct)
printf ("\nCorrection file '%s' compiled.\n\n", filename);
else
{
printf ("\n\nEncoding successful!\n\n");
if (fls)
{
if ((raus = fopen ("7plus.fls", OPEN_WRITE_TEXT)) == NULL)
return (14);
fnsplit (filename, NULL, NULL, _file, NULL);
fprintf (raus, "%d %s\n", parts, _file);
fclose (raus);
}
}
fclose (rein);
return (0);
}